use std::sync::{Arc, Mutex};
use std::thread;
use crossbeam_channel::{Sender, Receiver, unbounded, bounded};
use crate::context::Context;
use crate::message::Message;
use crate::actors::Actor;
use crate::mailbox::{MailboxSender, MailboxType};
use futures::future::BoxFuture;
use futures::FutureExt;

// 定义 CrossbeamMailbox
pub struct CrossbeamMailbox {
    sender: Sender<Box<dyn Message>>,
}

impl CrossbeamMailbox {
    pub fn new(actor: Arc<Mutex<dyn Actor + Send>>, mailbox_type: MailboxType) -> Self {
        let (sender, receiver) = match mailbox_type {
            MailboxType::Unbounded => unbounded(),
            MailboxType::Bounded(size) => bounded(size),
        };
        let actor_clone = actor.clone();
        thread::spawn(move || {
            let context = Context::new(receiver);
            loop {
                if let Ok(msg) = context.receiver.recv() {
                    let mut actor = actor_clone.lock().unwrap();
                    actor.receive(&context, msg);
                }
            }
        });

        CrossbeamMailbox { sender }
    }
}

impl MailboxSender for CrossbeamMailbox {
    fn send(&self, msg: Box<dyn Message>) -> BoxFuture<'static, ()> {
        futures::future::ready(self.sender.send(msg).map(|_| ())).boxed()
    }
}